#include <stdio.h>
#include <sys/types.h>          
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "sem.h"
#include <termios.h>
#include <fcntl.h>
#include <sys/stat.h>
#define SEND_OK 0xAA
#include <pthread.h>
#include <stdint.h>
#define STORAGE_NO	'2'



void serial_init(int fd)
{
	struct termios options;
	tcgetattr(fd, &options);
	options.c_cflag |= ( CLOCAL | CREAD );
	options.c_cflag &= ~CSIZE;
	options.c_cflag &= ~CRTSCTS;
	options.c_cflag |= CS8;
	options.c_cflag &= ~CSTOPB;
	options.c_iflag |= IGNPAR;
	options.c_iflag &= ~(ICRNL | IXON);
	options.c_oflag = 0;
	options.c_lflag = 0;
	cfsetispeed(&options, B115200);
	cfsetospeed(&options, B115200);
	tcsetattr(fd,TCSANOW,&options);
}


typedef struct
{
	uint8_t head[3];	 //标识位st:
	uint8_t type;		 //数据类型
	uint8_t snum;		 //仓库编号
	uint8_t temp[2];	 //温度	
	uint8_t hum[2];		 //湿度
	uint8_t x;			 //三轴信息
	uint8_t y;			 
	uint8_t z;			 
	uint32_t ill;		 //光照
	uint32_t bet;		 //电池电量
	uint32_t adc; 		 //电位器信息
}sendEnv;	


void *thread_func1();
void *thread_func2();
void *thread_func3();

void shm_create();

typedef struct linklist{
	sendEnv data;
	struct linklist *next;
}linklist_t;

linklist_t *create_linklist(void);
int insert_linklist(linklist_t *l,sendEnv x);
int show_linklist(linklist_t *l);

pthread_mutex_t mutex; //需要定义在全局
linklist_t *l;
sendEnv myEnv = {};
int dev_uart_fd;
sendEnv *pmyEnv;
int semid;

int main(int argc, const char *argv[])
{
	pthread_t tid1, tid2, tid3;
	pthread_mutex_init(&mutex,NULL);

	l = create_linklist();
	shm_create();

	if((pthread_create(&tid1,NULL,thread_func1,NULL)) != 0)
	{
		perror("fail to pthread1");
		exit(1);
	}
	/*
	if((pthread_create(&tid1,NULL,thread_func2,NULL)) != 0)
	{
		perror("fail to pthread1");
		exit(1);
	}
*/
	if((pthread_create(&tid1,NULL,thread_func3,NULL)) != 0)
	{
		perror("fail to pthread1");
		exit(1);
	}


	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
	pthread_join(tid3,NULL);



	return 0;
}


void *thread_func1()
{
	int ret = 0;
	if((dev_uart_fd = open("/dev/ttyUSB0", O_RDWR)) < 0)
	{
		perror("uart uart err");
		exit(1);
	}
	serial_init(dev_uart_fd);
	unsigned char x = 0x91;
	printf("return:%d\n",write(dev_uart_fd, &x, 4));

	while(1)
	{

		if(ret = read(dev_uart_fd, &myEnv, sizeof(myEnv)) < 0)
		{
			perror("fail to read");
			exit(1);
		}
	  	printf("%uF,%uF,%u%%,%u%%,%um/(s*s),%um/(s*s),%um/(s*s),%uLUX,%umV,%umV\n", myEnv.temp[0], myEnv.temp[1], myEnv.hum[0], myEnv.hum[1], myEnv.x, myEnv.y, myEnv.z, myEnv.ill, myEnv.bet, myEnv.adc);

	}

}


void *thread_func2(void )
{
//	pthread_mutex_lock(&mutex);
while(1)
{
	insert_linklist(l,myEnv);	
	show_linklist(l);
}
//	pthread_mutex_unlock(&mutex);
}



linklist_t *create_linklist(void)
{
	linklist_t *l = (linklist_t *)malloc(sizeof(linklist_t));
	l->next = NULL;
	return l;
}

int insert_linklist(linklist_t *l,sendEnv buf)
{
	linklist_t *node = (linklist_t *)malloc(sizeof(linklist_t));
	node->data = buf;
	node->next = NULL;
	linklist_t *p = l;
	while(p->next)
		p = p->next;
	p->next = node;
	printf("hehe\n");
	return 1;

}
int show_linklist(linklist_t *l)
{
	linklist_t *p = l;
	while(p->next != NULL)
	{
		printf("haha%uF\n",p->next->data.temp[0]);
		p = p->next;
	}
	return 1;
}

void *thread_func3()
{
while(1)
{
	sem_p(semid, 0);
	*pmyEnv = myEnv;
	printf("shm:%uF\n", pmyEnv->temp[0]);
	sleep(1);
	sem_v(semid, 0);
}
}
void shm_create()
{


	int shmid;
	key_t key;
	key = ftok("/",'a');
	if(key < 0)
	{
		perror("fail to ftok");
		exit(-1);
	}
	fisrt_init_sem(&semid, &key);//初始化信号量
	init_sem(semid, 0, 1);

	shmid = shmget(key, sizeof(myEnv),IPC_CREAT | IPC_EXCL | 0777);
	if(shmid < 0)
	{
		if (errno == EEXIST)
		{
			shmid = shmget(key,0,0);
		}
		else
		{
			perror("fail to shmget");
			exit(-1);
		}
	}
	if((pmyEnv = (sendEnv *)shmat(shmid,NULL,0)) ==(sendEnv *)-1 )
	{
		perror("fail to shmmat");
		exit(-1);
	}
}
